#pragma once
#include "Keyboard.h"
#include "NumberKeyboard.h"
#include <QPointer>
#include <QWidget>
#include <QApplication>
#include <QDebug>
#include <QTimer>
#include <QLayout>
#include <QScopedPointer>
#include <QEvent>
#include <QCloseEvent>

namespace AeaQt
{
    class KeyboardManager : public QObject
    {
        Q_OBJECT

    public:
        enum Type {
            Standard,
            Number
        };

        static KeyboardManager &getInstance()
        {
            static KeyboardManager instance;
            return instance;
        }

        // 标准键盘预加载
        void preloadKeyboard()
        {
            if (keyboardPointer_.isNull())
            {
                ensurePermanentContainer();
                keyboardPointer_ = new Keyboard(permanentContainer);
                keyboardPointer_->setAttribute(Qt::WA_DeleteOnClose, false);
                keyboardPointer_->show();
                keyboardPointer_->hide();
                qDebug() << "Keyboard preloaded successfully";
                QTimer::singleShot(200, this, [this]() {});
            }
        }

        // 数字键盘预加载
        void preloadNumberKeyboard()
        {
            if (numberKeyboardPointer_.isNull())
            {
                ensurePermanentContainer();
                numberKeyboardPointer_ = new NumberKeyboard(permanentContainer);
                numberKeyboardPointer_->setAttribute(Qt::WA_DeleteOnClose, false);
                numberKeyboardPointer_->show();
                numberKeyboardPointer_->hide();
                qDebug() << "NumberKeyboard preloaded successfully";
                QTimer::singleShot(200, this, [this]() {});
            }
        }

        // 获取标准键盘
        Keyboard *getKeyboard(QWidget *parent = nullptr)
        {
            ensurePermanentContainer();
            if (keyboardPointer_.isNull())
            {
                keyboardPointer_ = new Keyboard(permanentContainer);
                keyboardPointer_->setAttribute(Qt::WA_DeleteOnClose, false);
                keyboardPointer_->installEventFilter(this);
            }
            moveKeyboardToParent(keyboardPointer_, parent);
            return keyboardPointer_.data();
        }

        // 获取数字键盘
        NumberKeyboard *getNumberKeyboard(QWidget *parent = nullptr)
        {
            ensurePermanentContainer();
            if (numberKeyboardPointer_.isNull())
            {
                numberKeyboardPointer_ = new NumberKeyboard(permanentContainer);
                numberKeyboardPointer_->setAttribute(Qt::WA_DeleteOnClose, false);
                numberKeyboardPointer_->installEventFilter(this);
            }
            moveKeyboardToParent(numberKeyboardPointer_, parent);
            return numberKeyboardPointer_.data();
        }

        // 释放标准键盘
        void releaseKeyboard()
        {
            releaseKeyboardImpl(keyboardPointer_);
        }

        // 释放数字键盘
        void releaseNumberKeyboard()
        {
            releaseKeyboardImpl(numberKeyboardPointer_);
        }

        bool isKeyboardCreated() const
        {
            return !keyboardPointer_.isNull();
        }

        bool isNumberKeyboardCreated() const
        {
            return !numberKeyboardPointer_.isNull();
        }

    protected:
        bool eventFilter(QObject *watched, QEvent *event) override
        {
            if (event->type() == QEvent::Close)
            {
                if (keyboardPointer_ && keyboardPointer_->parent() == watched)
                    releaseKeyboard();
                if (numberKeyboardPointer_ && numberKeyboardPointer_->parent() == watched)
                    releaseNumberKeyboard();
            }
            else if (event->type() == QEvent::DeferredDelete)
            {
                if (watched == keyboardPointer_)
                {
                    qDebug() << "Prevented keyboard from being deleted";
                    return true;
                }
                if (watched == numberKeyboardPointer_)
                {
                    qDebug() << "Prevented number keyboard from being deleted";
                    return true;
                }
            }
            return QObject::eventFilter(watched, event);
        }

    private:
        KeyboardManager() : QObject(nullptr), permanentContainer(nullptr) {}
        ~KeyboardManager()
        {
            if (keyboardPointer_)
            {
                keyboardPointer_->setParent(nullptr);
                delete keyboardPointer_.data();
            }
            if (numberKeyboardPointer_)
            {
                numberKeyboardPointer_->setParent(nullptr);
                delete numberKeyboardPointer_.data();
            }
            delete permanentContainer;
        }

        KeyboardManager(const KeyboardManager &) = delete;
        KeyboardManager &operator=(const KeyboardManager &) = delete;

        void ensurePermanentContainer()
        {
            if (!permanentContainer)
            {
                permanentContainer = new QWidget();
                permanentContainer->hide();
                permanentContainer->setObjectName("KeyboardPermanentContainer");
                connect(qApp, &QApplication::aboutToQuit, this, [this]()
                        {
                            if (keyboardPointer_)
                            {
                                keyboardPointer_->setParent(nullptr);
                                delete keyboardPointer_.data();
                            }
                            if (numberKeyboardPointer_)
                            {
                                numberKeyboardPointer_->setParent(nullptr);
                                delete numberKeyboardPointer_.data();
                            }
                            delete permanentContainer;
                            permanentContainer = nullptr;
                        });
            }
        }

        template<typename T>
        void moveKeyboardToParent(QPointer<T> &keyboard, QWidget *parent)
        {
            if (keyboard->parent() != parent && parent != nullptr)
            {
                if (keyboard->parentWidget() && keyboard->parentWidget()->layout())
                {
                    keyboard->parentWidget()->layout()->removeWidget(keyboard.data());
                }
                keyboard->setParent(parent);
                qDebug() << "Moved keyboard to new parent";
                if (parent->isVisible())
                {
                    keyboard->show();
                }
                parent->installEventFilter(this);
            }
        }

        template<typename T>
        void releaseKeyboardImpl(QPointer<T> &keyboard)
        {
            if (!keyboard.isNull() && permanentContainer)
            {
                if (keyboard->parentWidget() && keyboard->parentWidget()->layout())
                {
                    keyboard->parentWidget()->layout()->removeWidget(keyboard.data());
                }
                keyboard->hide();
                keyboard->setParent(permanentContainer);
                qDebug() << "Keyboard returned to permanent container";
            }
        }

        QWidget *permanentContainer;
        QPointer<Keyboard> keyboardPointer_;
        QPointer<NumberKeyboard> numberKeyboardPointer_;
    };
}